Uzun zamandır Python ile ilgili bir şeyler yayınlamıyorum, bu yazımda önceki yazılardan biraz daha farklı olarak Python ile bir Transparan Proxy Sunucusu geliştireceğiz.
Öncelikli olarak Proxy Sunucusu nedir ona bakalım.
Proxy Sunucu Bilgisayar ağlarında istemcinin internet veya bir sunucuya bağlanırken kullanılan ara sunucudur. İstekler veya talepler önce bu sunucuya gider ardından hedef sunucuya ulaşır.
Bu sayede hız, kontrol ve en önemlisi güvenlik konusunda bize yardımcı olurlar. Yaygın olarak internet veya hedef-istemci adreslerinin kayıt altına alınması “loglanması” için kullanılır.
Farklı kullanım yönlerinde verinin istemci veya sunucuya ulaşmadan bir anti-virüs tarafından taratılması yada verilerin ön belleğe alınarak ilgili veriye daha hızlı ulaşım sağlanması noktasında yardımcı olabilir.
Biz İstemci-Sunucu verisinin kayıt altına alınması noktasında bir sistem geliştireceğiz.
Yapacağımız işlem 80 portundan çıkan verileri 9091 portuna Proxy Sunucumuza yönlendirerek bu verileri kayıt altına alıp daha sonra hedefe ulaştırılması olacaktır.
Kodumuzun Tam Hali : GitHub
Oluşturduğumuz log biçimi : Time—-ClientIPAdress—-ClientMACAdress—-Host:URL
Gerekli kütüphaneleri yüklemek için pip kodumuz :
pip install twisted
pip install –no-cache fastapi
pip install getmac
Adım adım ilerleyelim :
1.Adım olarak kütüphanelerimizi koda ekliyoruz;
1 2 3 4 5 6 7 8 9 10 11 12 |
# wwPHP.com Proxy Server 15-02-2023 # Kerem Bilgehan Gül # Adding Required Libraries. from twisted.web import http; from twisted.internet import reactor, protocol; from twisted.python import log; import re; import sys; import time; from getmac import get_mac_address; import datetime; import subprocess; |
2.Adım olarak log dosyamızın yolunu belirtiyoruz ;
1 |
log.startLogging(open('C:/LogDir/log.log', 'w')) |
3.Adım olarak Proxy Sunucumuz web datalarını kullandığı için twisted kütüphanemiz ile birlikte çağırdığımız http servisimizin parametrelerini yapılandırıyoruz;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
class ProxyClient(http.HTTPClient): def __init__(self, method, uri, postData, headers, originalRequest): self.method = method self.uri = uri self.postData = postData self.headers = headers self.originalRequest = originalRequest self.contentLength = None def sendRequest(self): self.sendCommand(self.method, self.uri) def sendHeaders(self): for key, values in self.headers: if key.lower() == 'connection': values = ['close'] elif key.lower() == 'keep-alive': next for value in values: self.sendHeader(key, value) self.endHeaders() def sendPostData(self): self.transport.write(self.postData) def connectionMade(self): self.sendRequest() self.sendHeaders() if self.method == 'POST': self.sendPostData() def handleStatus(self, version, code, message): self.originalRequest.setResponseCode(int(code), message) def handleHeader(self, key, value): if key.lower() == 'content-length': self.contentLength = value else: self.originalRequest.responseHeaders.addRawHeader(key, value) def handleResponse(self, data): data = self.originalRequest.processResponse(data) if self.contentLength != None: self.originalRequest.setHeader('Content-Length', len(data)) self.originalRequest.write(data) self.originalRequest.finish() self.transport.loseConnection() class ProxyClientFactory(protocol.ClientFactory): def __init__(self, method, uri, postData, headers, originalRequest): self.protocol = ProxyClient self.method = method self.uri = uri self.postData = postData self.headers = headers self.originalRequest = originalRequest def buildProtocol(self, addr): return self.protocol(self.method, self.uri, self.postData, self.headers, self.originalRequest) def clientConnectionFailed(self, connector, reason): log.err("Server connection failed: %s" % reason) self.originalRequest.setResponseCode(504) self.originalRequest.finish() |
4.Adım olarak Proxy Sunucumuza gelen parametleri yapılandırdığımız ve işletiğimiz sınıfımızı oluşturuyoruz;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
class ProxyClientFactory(protocol.ClientFactory): def __init__(self, method, uri, postData, headers, originalRequest): self.protocol = ProxyClient self.method = method self.uri = uri self.postData = postData self.headers = headers self.originalRequest = originalRequest def buildProtocol(self, addr): return self.protocol(self.method, self.uri, self.postData, self.headers, self.originalRequest) def clientConnectionFailed(self, connector, reason): log.err("Server connection failed: %s" % reason) self.originalRequest.setResponseCode(504) self.originalRequest.finish() class ProxyRequest(http.Request): def __init__(self, channel, queued, reactor=reactor): http.Request.__init__(self, channel, queued) self.reactor = reactor def process(self): host = self.getHeader('host') if not host: log.err("No host header given") self.setResponseCode(400) self.finish() return port = 80 if ':' in host: host, port = host.split(':') port = int(port) ClientsIp = self.getClientIP(); remote_MAC = get_mac_address(ip=ClientsIp); Dates = datetime.datetime.now(); f = open('C:/LogDir/proxy_'+str(Dates.strftime("%d-%m-%Y"))+'.log', 'a'); f.write(''+str(int(time.time()))+'----'+ClientsIp+'----'+remote_MAC+'----'+str(host)+':'+str(self.uri)+'\n'); f.close(); self.setHost(host, port) self.content.seek(0, 0) postData = self.content.read(); factory = ProxyClientFactory(self.method, self.uri, postData, self.requestHeaders.getAllRawHeaders(), self) self.reactor.connectTCP(host, port, factory) def processResponse(self, data): return data class TransparentProxy(http.HTTPChannel): requestFactory = ProxyRequest class ProxyFactory(http.HTTPFactory): protocol = TransparentProxy reactor.listenTCP(9091, ProxyFactory()) reactor.run() |
Kodumuz bu kadar.
Yukarıdaki kodlarda bulunan “C:/LogDir” kısımlarını kendinize göre düzenleyerek kullanabilirsiniz.
Sorularınız için aşağıda yer alan yorum bölümünü kullanabilirsiniz.